package com.atguigu.gmall.search.listener;

import com.atguigu.gmall.common.bean.ResponseVo;
import com.atguigu.gmall.common.consts.GmallConsts;
import com.atguigu.gmall.pms.entity.*;
import com.atguigu.gmall.search.feign.GmallPmsClient;
import com.atguigu.gmall.search.feign.GmallWmsClient;
import com.atguigu.gmall.search.repository.GoodsRepository;
import com.atguigu.gmall.search.vo.Goods;
import com.atguigu.gmall.search.vo.SearchAttrValue;
import com.atguigu.gmall.wms.entity.WareSkuEntity;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class RabbitmqListener {
    @Resource
    GoodsRepository goodsRepository;
    //消费整合后的队列消息
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(name = GmallConsts.SEARCH_QUEUE),
                    exchange = @Exchange(name = GmallConsts.SEARCH_EXCHANG ,
                            ignoreDeclarationExceptions = "true",
                            type = ExchangeTypes.TOPIC),
                    key = GmallConsts.SEARCH_ROUTING_KEY
            )
    })
    public void skuListener(Map<String,Object> params , Channel channel , Message message) throws IOException
    {

        try {
            //校验 redis中是否存在token，如果存在 拒绝本次请求
            //如果不存在 将token存到redis中设置过期时间 ， 处理本次请求
            if(Integer.parseInt(params.get("type").toString())==1){
                List<Long> ids = (List<Long>) params.get("param");
                if(!CollectionUtils.isEmpty(ids)){
                    ids.forEach(id->{
                        goodsRepository.deleteById(id);
                    });
                }
            }else if(Integer.parseInt(params.get("type").toString())==2){
                Long spuId = (Long) params.get("param");
                this.importSpu2Es(spuId);
            }

            channel.basicAck(message.getMessageProperties().getDeliveryTag() , false);
        } catch (Exception e) {
//            e.printStackTrace();
            if(message.getMessageProperties().isRedelivered()){
                channel.basicReject(message.getMessageProperties().getDeliveryTag() , false);
            }else{
                channel.basicNack(message.getMessageProperties().getDeliveryTag() , false,true);

            }
        }
    }




    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(name = GmallConsts.SEARCH_DEL_QUEUE),
                    exchange = @Exchange(name = GmallConsts.SEARCH_EXCHANG ,
                        ignoreDeclarationExceptions = "true",
                        type = ExchangeTypes.TOPIC),
                    key = GmallConsts.SEARCH_DEL_TOPIC_KEY
            )
    })
    public void skuDelListener(List<Long>ids , Channel channel , Message message) throws IOException {

        try {
            if(!CollectionUtils.isEmpty(ids)){
                ids.forEach(id->{
                    goodsRepository.deleteById(id);
                });
            }
            System.out.println(ids);
            channel.basicAck(message.getMessageProperties().getDeliveryTag() , false);
        } catch (Exception e) {
//            e.printStackTrace();
            if(message.getMessageProperties().isRedelivered()){
                channel.basicReject(message.getMessageProperties().getDeliveryTag() , false);
            }else{
                channel.basicNack(message.getMessageProperties().getDeliveryTag() , false,true);

            }
        }
    }

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(name = GmallConsts.SEARCH_SAVE_QUEUE),
                    exchange = @Exchange(name = GmallConsts.SEARCH_EXCHANG ,
                            ignoreDeclarationExceptions = "true",
                            type = ExchangeTypes.TOPIC),
                    key = GmallConsts.SEARCH_SAVE_TOPIC_KEY
            )
    })
    public void spuSaveListener(Long spuId , Channel channel , Message message) throws IOException {

        try {
            if(spuId!=null){
                importSpu2Es(spuId);
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag() , false);
        } catch (Exception e) {
//            e.printStackTrace();
            if(message.getMessageProperties().isRedelivered()){
                channel.basicReject(message.getMessageProperties().getDeliveryTag() , false);
            }else{
                channel.basicNack(message.getMessageProperties().getDeliveryTag() , false,true);

            }
        }
    }
    @Resource
    GmallPmsClient gmallPmsClient;
    @Resource
    GmallWmsClient gmallWmsClient;
    private void importSpu2Es(Long spuId) {
        //1、根据spuId查询spu对象
        ResponseVo<SpuEntity> responseVo = gmallPmsClient.querySpuById(spuId);
        SpuEntity spuEntity = responseVo.getData();
        if(spuEntity==null){
            return;
        }
        //- 2、查询品牌
        Long brandId = spuEntity.getBrandId();
        ResponseVo<BrandEntity> brandEntityResponseVo = gmallPmsClient.queryBrandById(brandId);
        BrandEntity brandEntity = brandEntityResponseVo.getData();
        //- 3、 查询分类
        Long categoryId = spuEntity.getCategoryId();
        ResponseVo<CategoryEntity> categoryEntityResponseVo = gmallPmsClient.queryCategoryById(categoryId);
        CategoryEntity categoryEntity = categoryEntityResponseVo.getData();
        //- 4、查询spu的检索属性
        ResponseVo<List<SpuAttrValueEntity>> searchAttrValueResponseVo = gmallPmsClient.listSearchAttrValueBySpuId(spuId);
        List<SpuAttrValueEntity> spuAttrValueEntities = searchAttrValueResponseVo.getData();
        //- 5、查询spu下的所有sku
        ResponseVo<List<SkuEntity>> skuEntitiesResponseVo = gmallPmsClient.listBySpuId(spuId);
        List<SkuEntity> skuEntities = skuEntitiesResponseVo.getData();
        //遍历sku集合
        if(CollectionUtils.isEmpty(skuEntities)){
            return;
        }
        List<Goods> goodsList = skuEntities.stream().map(skuEntity -> {
            Goods goods = new Goods();
            goods.setSkuId(skuEntity.getId());
            goods.setDefaultImage(skuEntity.getDefaultImage());
            goods.setPrice(skuEntity.getPrice());
            goods.setTitle(skuEntity.getTitle());
            goods.setSubtitile(skuEntity.getSubtitle());
            goods.setCreateTime(spuEntity.getCreateTime());
            if(categoryEntity!=null){
                goods.setCategoryId(categoryEntity.getId());
                goods.setCategoryName(categoryEntity.getName());
            }
            if(brandEntity!=null){
                goods.setBrandId(brandEntity.getId());
                goods.setBrandName(brandEntity.getName());
                goods.setLogo(brandEntity.getLogo());
            }
            //库存数据： 需要skuid查询
            ResponseVo<List<WareSkuEntity>> wareSkuEntitiesResponseVo = gmallWmsClient.listBySkuId(skuEntity.getId());
            List<WareSkuEntity> wareSkuEntities = wareSkuEntitiesResponseVo.getData();
            if(!CollectionUtils.isEmpty(wareSkuEntities)){
                //如果库存集合不为空，累加销量数据：
                Long sales = wareSkuEntities.stream().map(WareSkuEntity::getSales)
                        .reduce((a, b) -> a + b).get();
                //如果库存集合不为空, 判断如果任意一个仓库 有库存 设置goods有货
                //集合中的每个元素进行遍历 只要有一个满足anyMatch中断言条件的  返回true 否则返回false
                boolean store = wareSkuEntities.stream().anyMatch(wareSkuEntity -> wareSkuEntity.getStock()
                        - wareSkuEntity.getStockLocked() > 0);
                goods.setSales(sales);
                goods.setStore(store);

            }
            //检索属性： 需要skuid查询+ 之前spu的
            ResponseVo<List<SkuAttrValueEntity>> skuSearchAttrValuesResponseVo = gmallPmsClient.searchAttrValues(skuEntity.getId());
            List<SkuAttrValueEntity> skuAttrValueEntities = skuSearchAttrValuesResponseVo.getData();
//                    spuAttrValueEntities  + skuAttrValueEntities
            //组装spuAttrValueEntities  + skuAttrValueEntities到 SearchAttrValue集合中
            List<SearchAttrValue> searchAttrs = new ArrayList<>();
            if(!CollectionUtils.isEmpty(spuAttrValueEntities)){
                searchAttrs.addAll(spuAttrValueEntities.stream().map(spuAttrValueEntity -> {
                    SearchAttrValue searchAttrValue = new SearchAttrValue();
                    BeanUtils.copyProperties(spuAttrValueEntity,searchAttrValue);
                    return searchAttrValue;
                }).collect(Collectors.toList()));
            }
            if(!CollectionUtils.isEmpty(skuAttrValueEntities)){
                searchAttrs.addAll(skuAttrValueEntities.stream().map(skuAttrValueEntity -> {
                    SearchAttrValue searchAttrValue = new SearchAttrValue();
                    BeanUtils.copyProperties(skuAttrValueEntity,searchAttrValue);
                    return searchAttrValue;
                }).collect(Collectors.toList()));
            }
            goods.setSearchAttrs(searchAttrs);
            return goods;
        }).collect(Collectors.toList());
        //批量保存
        goodsRepository.saveAll(goodsList);


    }

}
